const genArr = <T>(val: T, times: number): T[] => {
  return new Array(times).fill(val)
}

// 函数类型别名泛型
type GenArr = <T>(val: T, times: number) => T[]
const genFn: GenArr = (val, times) => {
  return new Array(times).fill(val)
}

// genArr(123,3).map(item=>item.length) // Property 'length' does not exist on type 'number'.
genArr(123, 3).map(item => item.toFixed())
console.log(genArr('爸爸', 3).map(item => item.split(''))) // 根据val类型, 可以提示响应类型的方法

// 泛型约束, 假如我只允许带length属性的类型传入
interface WithLength {
  length: number
}

const genFn2 = <T extends WithLength>(val: T, times: number): T[] => {
  return new Array(times).fill(val)
}
genFn2([1, 2, 3], 2)
genFn2('爸爸', 2)
// genFn2(123,2) //Argument of type '123' is not assignable to parameter of type 'WithLength

// 泛型约束, 只允许访问对象存在的属性
function showProp<T, K extends keyof T> (obj: T, prop: K) {
  return obj[prop]
}

const person1 = {
  name: 'Samuel',
  age: 26,
  gender: 'Male'
}
console.log(showProp(person1, 'age'))
// console.log(showProp(person1,"addr")) //Argument of type '"addr"' is not assignable to parameter of type '"age" | "name" | "gender"'.
